﻿using MongoDB.Driver;
using Sustainalytics.BusinessResearchProductStates.Entities.ResearchState;
using Sustainalytics.ClientDW.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Sustainalytics.ScreeningTool.Synchronization.Caches
{
    public class CompanyIdsCache : DictionaryCache<Guid, IEnumerable<Guid>>
    {
        public IEnumerable<Guid> GetCoverageEntityIdsByResearchParentId(Guid researchParentId)
            => GetValueOrEmpty(researchParentId, Enumerable.Empty<Guid>());

        public IEnumerable<Guid> GetResearchParentIds() => dictionary.Keys;

        public bool IsCoverage(Guid companyId) => dictionary.Values.SelectMany(x => x).Contains(companyId);
    }

    public class CompanyIdsCacheLoader : ICacheLoader<CompanyIdsCache>
    {
        private readonly CompanyIdsCache cache;
        private readonly IMongoCollection<CorporateData> collection;

        public CompanyIdsCacheLoader(CompanyIdsCache cache, IMongoCollection<CorporateData> collection)
        {
            this.cache = cache;
            this.collection = collection;
        }

        public async Task LoadAsync(ClientFacingProduct clientFacingProduct)
        {
            var result = await collection
                .Find(x => x.ResearchParentId != null)
                .Project(x => new
                {
                    CoverageEntityId = x.Id,
                    ResearchParentId = x.ResearchParentId.Value
                })
                .ToListAsync()
                .ConfigureAwait(false);

            var items = result
                .GroupBy(x => x.ResearchParentId)
                .ToDictionary(grp => grp.Key, grp => grp.Select(x => x.CoverageEntityId));

            cache.AddItems(items);
        }
    }
}
